package com.loveyukari.service;

import com.loveyukari.common.exception.InternalException;
import com.loveyukari.douyu.MessageService;
import com.loveyukari.model.*;
import com.loveyukari.utils.AliYunUtils;
import com.loveyukari.utils.HeyskySendUtils;
import com.loveyukari.utils.HttpUtils;
import com.loveyukari.utils.YukariUtil;
import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.lang.reflect.Array;
import java.text.SimpleDateFormat;
import java.util.*;

/**
*
*yangshaohua
*2017年4月11日下午3:25:53
**/
@Service
public class NewYukariRoomService implements MessageService {
 
	@Autowired
	private LiwuService liwuService;
	@Autowired
	private NewRegisterService newRegisterService;
	@Autowired
	private AuthService authService;
	@Autowired
	private VoteService voteService;
	@Autowired
	private DrawChatmsgService drawChatmsgService;
	@Autowired
	private DrawTicketService drawTicketService;
	@Autowired
	private YukariWebSocketService yukariWebSocketService;
	@Autowired
	private RoomService roomService;
	@Autowired
	private TmpService tmpService;
	@Autowired
	private PermissionService permissionService;
	@Autowired
	private XiaomaService xiaomaService;
	@Autowired
	private RoomGoldRankService roomGoldRankService;
	@Autowired
	private BanService banService;
	@Autowired
	private RedisService redisService;
	@Autowired
	private ServerService serverService;
	@Autowired
	private ShieldAuthService shieldAuthService;



	private Logger talkLog = LoggerFactory.getLogger("YukariTalk");
	private Logger roomLog = LoggerFactory.getLogger("YukariRoom");
	private Logger roomLiwu = LoggerFactory.getLogger("YukariRoomLiwu");
	private Logger roomTalk = LoggerFactory.getLogger("YukariRoomTalk");
	private Logger authLog = LoggerFactory.getLogger("AuthLog");
	
	private Logger otherLog = LoggerFactory.getLogger("YukariRoomOther");
	private Logger infoLog = LoggerFactory.getLogger(NewYukariRoomService.class);

	
	private long checkTime = 10*60*1000;
	
	private static boolean live = false;
//	private static boolean live = true;
	

	public static boolean isLive() {
		return live;
	}
//	private static final String MSG_HISTORY_KEY = "msg:history:";
	private boolean isHistoryMsg(JSONObject msg){
//		JSONObject v = msgRedisTemplate.opsForValue().get(MSG_HISTORY_KEY+msg.toString());
//		if (v != null){
//			return true;
//		} else {
//			msgRedisTemplate.opsForValue().set(MSG_HISTORY_KEY+msg.toString(), msg, 30, TimeUnit.MINUTES);
//			return false;
//		}
		return false;
	}
	
	private static final String MSG_QUEUE = "msg:queue";
	private static final String BAN_QUEUE = "ban:queue";
	@PostConstruct
	public void init(){
		new Thread(){
			@Override
			public void run() {
				while (true) {
					try {
						JSONObject msg = redisService.popListOne(MSG_QUEUE, JSONObject.class);
						if (msg == null){
							Thread.sleep(100);
						} else {
							parseMessage(msg);
						}
					} catch (Exception e) {
						infoLog.error(e.getMessage(),e);
					}
				}
			}
		}.start();
		new Thread(){
			@Override
			public void run() {
				while(true){
					try {
						Room room = roomService.init(196);
						live = room.getRoomStatus() == 1;
						lastLiveStartTime = room.getStartTime().getTime();
						break;
					} catch (Exception e) {
					}
				}
			}
		}.start();
		
	}
	
	public synchronized void messageWork(JSONObject msg) {
		if (isHistoryMsg(msg)){
			return;
		} else {
			redisService.setList(MSG_QUEUE,msg);
		}
	}
	
	//临时
	public Map<String,Object> tmp = new HashMap<String,Object>();
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private void parseMessage(JSONObject msg){
		String msgType = msg.getString("type");
		if (msgType.equals("rss")){ //开播监控
			roomLog.info(msg.toString());
			if (msg.optInt("ss") == 1){
				live = true;
				this.lastLiveStartTime = System.currentTimeMillis();
				newRegisterService.liveStartRegister();
			} else {
				stopLive();
			}
		} else if (msgType.equals("chatmsg")){//弹幕监控
			roomTalk.info(msg.toString());
			Auth auth = createAuth(msg);
			String txt = msg.optString("txt",null);
			if (StringUtils.isNotBlank(txt)){
//				this.danmakuListener(txt, auth);
				authService.setAuthTalk(auth.getId(), txt);
				if (live){
					newRegisterService.setRegisterAuthTalk(auth.getId());
				}
				voteService.vote(txt,auth.getId());
				if (drawChatmsgService.isDrawChatmsg(txt)){
					String bnn = msg.optString("bnn");
					int bl = msg.optInt("bl",-1);
					if (drawChatmsgService.isFans(bnn, bl)){
						drawChatmsgService.addAuth(auth.getId());
					}
				}
				if (drawTicketService.isDrawChatmsg(txt)){
					drawTicketService.addAuth(auth.getId());
				}
				if (!shieldAuthService.isShieldAuth(auth.getId())){
					yukariWebSocketService.sendChatmsg(msg);
				}
//				if (StringUtils.equals(msg.optString("bnn"),"总监") || StringUtils.equals("#testBan",txt)){
//					JSONObject banJson = new JSONObject();
//					banJson.put("banTime",43200);
//					banJson.put("banName",msg.optString("nn"));
//					banJson.put("roomId",196);
//					msgRedisTemplate.opsForList().rightPush(BAN_QUEUE,banJson);
//				}
			}
		} else if (msgType.equals("dgb") ){//礼物监控
			roomLiwu.info(msg.toString());
			Auth auth = createAuth(msg);
			int gfid = msg.optInt("gfid",-1);
			if (gfid != -1){
				roomService.countLiwu(gfid,auth.getId());
				int hits = msg.optInt("hits",1);
				if (this.isAdd(gfid, hits) || permissionService.getAuthIdByPermission(3).contains(auth.getId())){
					this.addLiwu(gfid, auth.getId(), hits);
				}
				if (live){
					newRegisterService.setRegisterAuthTalk(auth.getId());
				}
			}
		} else if (msgType.equals("bc_buy_deserve")){//酬勤监控
			roomLiwu.info(msg.toString());
			Auth auth = createAuthByCq(msg);
			Integer gfid = msg.optInt("lev",-1);
			if (gfid != -1){
				roomService.countLiwu(gfid,auth.getId());
				int hits = msg.optInt("hits",1);
				this.addLiwu(gfid, auth.getId(), hits);
				if (live){
					newRegisterService.setRegisterAuthTalk(auth.getId());
				}
			}
		} else if (msgType.equals("anbc")){//贵族开通监控
			String donk = msg.optString("donk");
			if ("小缘".equals(donk)){
				roomLiwu.info(msg.toString());
				Auth auth = createAuthByGz(msg);
				int gfid = msg.optInt("nl",-1);
				if (gfid != -1){
					this.addLiwu(gfid+10, auth.getId(), 1);
				}
				if (live){
					newRegisterService.setRegisterAuthTalk(auth.getId());
				}
			}
		} else if (msgType.equals("uenter")){//进房间监控
			roomTalk.info(msg.toString());
			Auth auth = createAuth(msg);
			authService.setAuthTalk(auth.getId(), "【进入直播间】");
			if (live){
				newRegisterService.setRegisterAuthTalk(auth.getId());
			}
			yukariWebSocketService.sendUenter(msg);
		} else if (msgType.equals("ssd")){ //超级弹幕
			if (msg.optInt("trid") == 196){
				yukariWebSocketService.sendHorn(msg);
				roomLog.info(msg.toString());
			}
		} else if (msgType.equals("2")){//抽奖
			roomLog.info(msg.toString());
		} else if (msgType.equals("ranklist")){ //排行榜
			otherLog.info(msg.toString());
			JSONArray list = msg.optJSONArray("list");
			roomGoldRankService.addOrUpdateList(list);
		} else if (msgType.equals("cthn")) { //分区喇叭
			otherLog.info(msg.toString());
			if (msg.optInt("drid") == 196) {
				int uid = msg.optInt("uid");
				String txt = msg.optString("chatmsg");
				txt = "<font style='color:red;'>" + txt + "</font>";
				authService.setAuthTalk(uid, txt);
				yukariWebSocketService.sendHorn(msg);
			}
		} else if (msgType.equals("1")) {
			roomLog.info(msg.toString());
			int did = msg.optInt("did");
			int sid = msg.optInt("sid");
			if (did != 0 && sid != 0){
				long endtime = msg.optLong("endtime") * 1000;
				Date endDate = new Date(endtime);
				banService.saveBanAccount(did, sid, endDate, "直播间禁言");
			}
		} else if (msgType.equals("cyclepqs")){
			otherLog.info(msg.toString());
			int res = msg.optInt("res");
			if (res == 0){
				String qid = msg.optString("qid");
				HashMap<String, Object> map = new LinkedHashMap<>();
				map.put("type","pqaq");
				map.put("uid","74134174");
				map.put("rid","196");
				map.put("acid","activity_cycledt");
				map.put("qid",qid);
				map.put("aid","2");
				serverService.sendMsg(map);
				otherLog.info(JSONObject.fromObject(map).toString());
			}
		} else if (false){
		} else {
			if (msg.has("rid")){
				if(msg.optInt("rid") == 196){
					otherLog.info(msg.toString());
				}
			} else {
				otherLog.info(msg.toString());
			}
		}
	}
	
	
	
	private void addLiwu(int gfid,int authId,int hits){
		Liwu liwu = liwuService.getLiwuByAuthAndGfid(authId, gfid);
		LiwuStyle liwuStyle = liwuService.getLiwuStyleByGfid(gfid);
		if (liwuStyle == null){
			return;
		}
		if (liwu == null){
			liwuService.addLiwu(gfid, authId, hits);
		} else if (liwu.getHits() < hits){
			if (liwu.getStatus() == 0 || this.isAdd(gfid, hits - liwu.getHits())) {
				liwu.setHits(hits);
				liwu.setGiveTime(new Date());
				liwu.setStatus(0);
				liwuService.updateLiwu(liwu);
			}
		} else {
			liwuService.addLiwu(gfid, authId, hits);
		}
	}
	
	private boolean isAdd(int gfid,int hits){
		LiwuStyle style = liwuService.getLiwuStyleByGfid(gfid);
		if (style == null) {
			infoLog.error("礼物id: "+gfid+" 无法获取样式信息");
			return true;
		} else {
			return style.getFree() == 0 && hits > 1960/style.getPc();
		}
	}
	
	
//	private long lastDanmakuTime = 0;
//	private void danmakuListener(final String txt,Auth auth){
//		if (YukariUtil.checkName(auth.getName())){
//			talkLog.info(auth.getName()+": "+txt);
//			long now = System.currentTimeMillis();
//			if ((!live) && now - lastDanmakuTime > checkTime){
//				final List<Auth> list = authService.getYukariTalkAuthList();
//				new Thread(){
//					public void run() {
//						List<List<Auth>> authLists = new ArrayList<List<Auth>>();
//						if (list.size() == 0){
//							return;
//						} else {
//							//短信最多一次支持200条，因此以200作为间隔
//							int s = list.size() / 200 + 1;
//							if (s == 1){
//								authLists.add(list);
//							} else {
//								for (int i = 0; i < s; i++) {
//									int start = 200*i;
//									int end = list.size() < start + 200 ? list.size() : start + 200;
//									authLists.add(list.subList(start,end ));
//								}
//							}
//						}
//						for (List<Auth> authList : authLists) {
//							//组装短信请求并发送
//							StringBuilder sb = new StringBuilder();
//							StringBuilder gjsb = new StringBuilder();
//							String phone = sb.substring(0, sb.length()-1);
//							AliYunUtils.sendTalk(phone, "196",txt);
//							if (gjsb.length() > 0){
//								HeyskySendUtils.sendMessage("小缘:"+txt, gjsb.substring(0, gjsb.length()-1));
//							}
//						}
//					};
//				}.start();
//			}
//			this.lastDanmakuTime = now;
//		} else if (YukariUtil.checkUid(auth.getId())) {
//			talkLog.info(auth.getName()+": "+txt);
////			AliYunUtils.sendTalk(mePhone, "196",txt);
//		}
//	}
	
	
	private long lastLiveStopTime;
	private long lastLiveStartTime;
	//开播提醒


	private void stopLive(){
		live = false;
		this.lastLiveStopTime = System.currentTimeMillis();
		List<Liwu> list = liwuService.getLiwu(-1);
		if (list.size()> 200){
			List<Integer> ids = new ArrayList<Integer>();
			for (int i = 0; i < list.size(); i++) {
				Liwu liwu = list.get(i);
				if (liwu.getGiveTime().getTime() < lastLiveStartTime){
					ids.add(liwu.getId());
				}
			}
			if (!ids.isEmpty()){
				liwuService.closeLiwu(ids);
			}
		}
	}







	
	//弹幕、礼物获取用户
	private Auth getAuth(int id,String name,int authority,String icon,int lv,String bnn,int bl,int nl){
		if (id != -1){
			Auth auth = authService.getCacheAuth(id);
			if (auth == null) {
				if (StringUtils.isNotBlank(name)){
					auth = new Auth();
					auth.setId(id);
					auth.setName(name);
					auth.setAuthority(authority);
					auth.setIcon(icon);
					auth.setLv(lv);
					auth.setGuizu(nl>-1?nl:0);
					if (StringUtils.equals(bnn, "196")){
						auth.setFansLv(bl);
					}
					this.authService.addAuth(auth);
					return authService.getCacheAuth(id);
				} else {
					return null;
				}
			} else {
				if (StringUtils.isNotBlank(name) && !StringUtils.contains(name,"�") && !StringUtils.equals(auth.getName(), name)){
					authLog.info("update auth name,old: "+auth.getId()+","+auth.getName()+" new: "+id+","+name);
					auth = this.authService.updateAuthName(name, id);
				} 
				if (StringUtils.isNotBlank(icon) && !StringUtils.equals(auth.getIcon(), icon)){
					authLog.info("update auth icon,old: "+auth.getId()+","+auth.getIcon()+" new: "+id+","+icon);
					auth = this.authService.updateAuthIcon(icon, id);
				}
				if (lv > auth.getLv()){
					authLog.info("update auth lv,old: "+auth.getId()+","+auth.getLv()+" new: "+id+","+lv);
					auth = this.authService.updateAuthLv(lv, id);
				}
				if (bl > auth.getFansLv()){
					if (StringUtils.equals(bnn, "196")){
						authLog.info("update auth fans lv,old: "+auth.getId()+","+auth.getFansLv()+" new: "+id+","+bl);
						auth = this.authService.updateAuthFansLv(bl, id);
					}
				}
				if (nl != -1 && nl != auth.getGuizu()){
					authLog.info("update auth guizu lv,old: "+auth.getId()+","+auth.getGuizu()+" new: "+id+","+nl);
					auth = this.authService.updateAuthGuizu(nl,id);
				}
				if (auth.getAuthority() == 0 && authority != 0){
					auth = this.authService.updateAuthority(authority, id);
					if (authority == 1){
						permissionService.addAuthPermission(id,1);
						permissionService.addAuthPermission(id,2);
					}
				}
				return auth;
			}
		} else {
			return null;
		}
	}
	
	
	private Auth createAuth(JSONObject json){
		int id = json.optInt("uid",-1);
		String name = json.optString("nn",null);
		int authority = this.getAuthority(json);
		String icon = json.optString("ic","");
		int lv = json.optInt("level");
		String bnn = json.optString("bnn");
		int bl = json.optInt("bl");
		int nl = json.optInt("nl");
		return this.getAuth(id, name,authority,icon,lv,bnn,bl,nl);
	}
	
	private Auth createAuthByCq(JSONObject json){
		int sid = json.optInt("sid",-1);
		JSONObject jsonObject = json.optJSONObject("sui");
		String name = null;
		int authority = 0;
		if (jsonObject != null){
			authority = this.getAuthority(jsonObject);
			name = jsonObject.optString("nick", null);
		}
		String icon = json.optString("ic","");
		int lv = json.optInt("level");
		String bnn = json.optString("bnn");
		int bl = json.optInt("bl");
		return this.getAuth(sid, name,authority,icon,lv,bnn,bl,-1);
	}
	
	private Auth createAuthByGz(JSONObject json){
		int id = json.optInt("uid",-1);
		String name = json.optString("unk",null);
		String icon = json.optString("ic","");
		int nl = json.optInt("nl");
		return this.getAuth(id, name,0,icon,0,"",0,nl);
	}
	
	private int getAuthority(JSONObject json){
		int authority = 0;
		int rg = json.optInt("rg",1);
		if (rg == 4) {
			authority = 1;
		} else if (rg == 5) {
			authority = 3;
		}
		int pg = json.optInt("pg",1);
		if (pg == 5){
			authority = 2;
		}
		return authority;
	}
	

}
